home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / utilities / disk / device-handler.lha / Device-Handler / Source / Dev.c next >
Encoding:
C/C++ Source or Header  |  1995-01-24  |  9.2 KB  |  386 lines

  1.  
  2. #include <exec/memory.h>
  3. #include <exec/execbase.h>
  4. #include <devices/trackdisk.h>
  5. #include <dos/dosextens.h>
  6. #include <dos/filehandler.h>
  7.  
  8. #define __USE_SYSBASE 42
  9.  
  10. #include <proto/exec.h>
  11.  
  12. #include <string.h>
  13.  
  14. struct DosPacket *WaitDosPacket(struct MsgPort *);
  15. void __regargs ReplyDosPacket(struct DosPacket *,struct MsgPort *,LONG,LONG);
  16.  
  17. void __regargs OpenDH(struct DosPacket *,ULONG *);
  18. void __regargs CloseDH(struct DHHandle *,ULONG *);
  19.  
  20. LONG __regargs RawRead(struct DHHandle *,UBYTE *,LONG);
  21. LONG __regargs RawWrite(struct DHHandle *,UBYTE *,LONG);
  22.  
  23. struct ExecBase *SysBase;
  24.  
  25. struct DHHandle
  26.  {
  27.   struct IOStdReq *rh_IO;
  28.   struct DriveGeometry rh_DG;
  29.   ULONG rh_Len,rh_Pos,rh_Left;
  30.   UBYTE *rh_Buffer,*rh_Ptr;
  31.   BOOL rh_Write;
  32.  };
  33.  
  34. #define BCPL_MAX_LEN 256
  35. #define MIN __builtin_min
  36.  
  37. char VersionString[] = "$VER: Device-Handler 1.1 "__AMIGADATE__;
  38.  
  39. LONG __saveds DeviceHandler(void)
  40.  
  41. {
  42.  struct Process *MyProc;
  43.  struct DosPacket *Pkt;
  44.  struct DeviceNode *DeviceNode;
  45.  struct MsgPort *PacketPort;
  46.  BOOL Done;
  47.  ULONG OpenCnt;
  48.  
  49.  SysBase=*(struct ExecBase **)4L;
  50.  if ((MyProc=(struct Process *)SysBase->ThisTask)->pr_CLI) return 20L;
  51.  
  52.  Pkt=WaitDosPacket(&MyProc->pr_MsgPort);
  53.  DeviceNode=(struct DeviceNode *)BADDR(Pkt->dp_Arg3);
  54.  if (SysBase->LibNode.lib_Version<37)
  55.   {
  56.    ReplyDosPacket (Pkt,&MyProc->pr_MsgPort,DOSFALSE,ERROR_INVALID_RESIDENT_LIBRARY);
  57.    return 0L;
  58.   }
  59.  
  60.  if ((PacketPort=CreateMsgPort())==NULL)
  61.   {
  62.    ReplyDosPacket (Pkt,&MyProc->pr_MsgPort,DOSFALSE,ERROR_NO_FREE_STORE);
  63.    return 0L;
  64.   }
  65.  
  66.  DeviceNode->dn_Task=PacketPort;
  67.  Pkt->dp_Arg4=(LONG)PacketPort;
  68.  ReplyDosPacket (Pkt,PacketPort,DOSTRUE,Pkt->dp_Res2);
  69.  
  70.  Done=FALSE;
  71.  OpenCnt=0L;
  72.  
  73.  while (!Done)
  74.   {
  75.    Pkt=WaitDosPacket(PacketPort);
  76.  
  77.    switch (Pkt->dp_Type)
  78.     {
  79.      case ACTION_FINDINPUT:
  80.       OpenDH (Pkt,&OpenCnt);
  81.       ReplyDosPacket (Pkt,PacketPort,Pkt->dp_Res1,Pkt->dp_Res2);
  82.       break;
  83.      case ACTION_FINDOUTPUT:
  84.       OpenDH (Pkt,&OpenCnt);
  85.       ReplyDosPacket (Pkt,PacketPort,Pkt->dp_Res1,Pkt->dp_Res2);
  86.       break;
  87.      case ACTION_END:
  88.       CloseDH ((struct DHHandle *)Pkt->dp_Arg1,&OpenCnt);
  89.       ReplyDosPacket (Pkt,PacketPort,DOSTRUE,0L);
  90.       break;
  91.      case ACTION_READ:
  92.       if (!((struct DHHandle *)Pkt->dp_Arg1)->rh_Write)
  93.        {
  94.         LONG Bytes;
  95.  
  96.         Bytes=RawRead((struct DHHandle *)Pkt->dp_Arg1,(UBYTE *)Pkt->dp_Arg2,Pkt->dp_Arg3);
  97.         if (Bytes<0L) ReplyDosPacket (Pkt,PacketPort,-1L,ERROR_SEEK_ERROR);
  98.         else ReplyDosPacket (Pkt,PacketPort,Bytes,0L);
  99.        }
  100.       else ReplyDosPacket (Pkt,PacketPort,-1L,ERROR_OBJECT_WRONG_TYPE);
  101.       break;
  102.      case ACTION_WRITE:
  103.       if (((struct DHHandle *)Pkt->dp_Arg1)->rh_Write)
  104.        {
  105.         LONG Bytes;
  106.  
  107.         Bytes=RawWrite((struct DHHandle *)Pkt->dp_Arg1,(UBYTE *)Pkt->dp_Arg2,Pkt->dp_Arg3);
  108.         if (Bytes<0L) ReplyDosPacket (Pkt,PacketPort,-1L,ERROR_SEEK_ERROR);
  109.         else ReplyDosPacket (Pkt,PacketPort,Bytes,0L);
  110.        }
  111.       else ReplyDosPacket (Pkt,PacketPort,-1L,ERROR_OBJECT_WRONG_TYPE);
  112.       break;
  113.      case ACTION_IS_FILESYSTEM:
  114.       ReplyDosPacket (Pkt,PacketPort,DOSFALSE,0L);
  115.       break;
  116.      default:
  117.       ReplyDosPacket (Pkt,PacketPort,DOSFALSE,ERROR_ACTION_NOT_KNOWN);
  118.     }
  119.  
  120.    if (OpenCnt==0L)
  121.     {
  122.      Forbid();
  123.      if (PacketPort->mp_MsgList.lh_Head->ln_Succ==NULL)
  124.       {
  125.        DeviceNode->dn_Task=NULL;
  126.        Done=TRUE;
  127.       }
  128.      Permit();
  129.     }
  130.   }
  131.  
  132.  DeleteMsgPort (PacketPort);
  133.  
  134.  return 0L;
  135. }
  136.  
  137. struct DosPacket *WaitDosPacket(struct MsgPort *PacketPort)
  138.  
  139. {
  140.  (void)WaitPort(PacketPort);
  141.  return (struct DosPacket *)GetMsg(PacketPort)->mn_Node.ln_Name;
  142. }
  143.  
  144. void __regargs ReplyDosPacket(struct DosPacket *Packet,
  145.                               struct MsgPort *PacketPort,
  146.                               LONG Res1,LONG Res2)
  147.  
  148. {
  149.  struct MsgPort *ReplyPort;
  150.  
  151.  ReplyPort=Packet->dp_Port;
  152.  Packet->dp_Port=PacketPort;
  153.  Packet->dp_Link->mn_Node.ln_Name=(char *)Packet;
  154.  Packet->dp_Res1=Res1;
  155.  Packet->dp_Res2=Res2;
  156.  
  157.  PutMsg (ReplyPort,Packet->dp_Link);
  158. }
  159.  
  160. void __regargs OpenDH(struct DosPacket *Pkt,ULONG *OpenCnt)
  161.  
  162. {
  163.  struct FileHandle *FH;
  164.  UBYTE *BStr,Name[BCPL_MAX_LEN],*Ptr;
  165.  ULONG Unit;
  166.  struct DHHandle *RH;
  167.  struct MsgPort *IOPort;
  168.  
  169.  Pkt->dp_Res1=DOSFALSE;
  170.  FH=(struct FileHandle *)BADDR(Pkt->dp_Arg1);
  171.  FH->fh_Port=(struct MsgPort *)FALSE;
  172.  FH->fh_Arg1=0L;
  173.  
  174.  BStr=(UBYTE *)BADDR(Pkt->dp_Arg3);
  175.  (void)memcpy(Name,&BStr[1],BStr[0]);
  176.  Name[BStr[0]]='\0';
  177.  
  178.  if (Ptr=strchr(Name,':')) (void)strcpy(Name,Ptr+1L);
  179.  if ((Ptr=strchr(Name,'/'))==NULL)
  180.   {
  181.    Pkt->dp_Res2=ERROR_BAD_STREAM_NAME;
  182.    return;
  183.   }
  184.  *Ptr++='\0';
  185.  
  186.  if ((Name[0]=='\0')||(*Ptr=='\0'))
  187.   {
  188.    Pkt->dp_Res2=ERROR_BAD_STREAM_NAME;
  189.    return;
  190.   }
  191.  
  192.  Unit=0L;
  193.  while (*Ptr)
  194.   if ((*Ptr<'0')||(*Ptr>'9'))
  195.    {
  196.     Pkt->dp_Res2=ERROR_BAD_NUMBER;
  197.     return;
  198.    }
  199.   else Unit=10L*Unit+(*Ptr++-'0');
  200.  
  201.  Pkt->dp_Res2=ERROR_NO_FREE_STORE;
  202.  if (RH=AllocVec(sizeof(struct DHHandle),MEMF_PUBLIC|MEMF_CLEAR))
  203.   {
  204.    if (IOPort=CreateMsgPort())
  205.     {
  206.      if (RH->rh_IO=CreateStdIO(IOPort))
  207.       {
  208.        if (OpenDevice(Name,Unit,(struct IORequest *)RH->rh_IO,0L)==0L)
  209.         {
  210.          RH->rh_IO->io_Command=TD_GETGEOMETRY;
  211.          RH->rh_IO->io_Length=sizeof(struct DriveGeometry);
  212.          RH->rh_IO->io_Data=&RH->rh_DG;
  213.          if (DoIO((struct IORequest *)RH->rh_IO)==0L)
  214.           if (RH->rh_Buffer=AllocMem(RH->rh_DG.dg_SectorSize,RH->rh_DG.dg_BufMemType))
  215.            {
  216.             RH->rh_Len=RH->rh_DG.dg_SectorSize*RH->rh_DG.dg_TotalSectors;
  217.             if (Pkt->dp_Type==ACTION_FINDOUTPUT)
  218.              {
  219.               RH->rh_Write=TRUE;
  220.               RH->rh_Left=RH->rh_DG.dg_SectorSize;
  221.               RH->rh_Ptr=RH->rh_Buffer;
  222.              }
  223.             else RH->rh_Write=FALSE;
  224.             FH->fh_Arg1=(LONG)RH;
  225.             Pkt->dp_Res1=DOSTRUE;
  226.             Pkt->dp_Res2=0L;
  227.  
  228.             (*OpenCnt)++;
  229.             return;
  230.            }
  231.          CloseDevice ((struct IORequest *)RH->rh_IO);
  232.         }
  233.        else Pkt->dp_Res2=ERROR_OBJECT_NOT_FOUND;
  234.  
  235.        DeleteStdIO (RH->rh_IO);
  236.       }
  237.      DeleteMsgPort (IOPort);
  238.     }
  239.    FreeVec (RH);
  240.   }
  241. }
  242.  
  243. void __regargs CloseDH(struct DHHandle *RH,ULONG *OpenCnt)
  244.  
  245. {
  246.  if (RH->rh_Write)
  247.   {
  248.    if (RH->rh_Left<RH->rh_DG.dg_SectorSize)
  249.     {
  250.      (void)memset(RH->rh_Ptr,'\0',RH->rh_Left);
  251.      RH->rh_IO->io_Command=CMD_WRITE;
  252.      RH->rh_IO->io_Length=RH->rh_DG.dg_SectorSize;
  253.      RH->rh_IO->io_Data=RH->rh_Buffer;
  254.      RH->rh_IO->io_Offset=RH->rh_Pos+RH->rh_Left-RH->rh_DG.dg_SectorSize;
  255.      (void)DoIO((struct IORequest *)RH->rh_IO);
  256.     }
  257.    RH->rh_IO->io_Command=CMD_UPDATE;
  258.    (void)DoIO((struct IORequest *)RH->rh_IO);
  259.   }
  260.  
  261.  FreeMem (RH->rh_Buffer,RH->rh_DG.dg_SectorSize);
  262.  
  263.  RH->rh_IO->io_Command=TD_MOTOR;
  264.  RH->rh_IO->io_Length=0L;
  265.  (void)DoIO((struct IORequest *)RH->rh_IO);
  266.  CloseDevice ((struct IORequest *)RH->rh_IO);
  267.  
  268.  DeleteMsgPort (RH->rh_IO->io_Message.mn_ReplyPort);
  269.  DeleteStdIO (RH->rh_IO);
  270.  
  271.  FreeVec (RH);
  272.  
  273.  (*OpenCnt)--;
  274. }
  275.  
  276. LONG __regargs RawRead(struct DHHandle *RH,UBYTE *Buffer,LONG Bytes)
  277.  
  278. {
  279.  LONG Total,RDBytes;
  280.  
  281.  if ((RH->rh_Pos+Bytes)>RH->rh_Len) Bytes=RH->rh_Len-RH->rh_Pos;
  282.  
  283.  Total=0L;
  284.  while (Bytes)
  285.   {
  286.    if (RH->rh_Left)
  287.     {
  288.      RDBytes=MIN(RH->rh_Left,Bytes);
  289.      (void)memcpy(Buffer,RH->rh_Ptr,RDBytes);
  290.  
  291.      Buffer+=RDBytes;
  292.      Bytes-=RDBytes;
  293.      Total+=RDBytes;
  294.  
  295.      RH->rh_Pos+=RDBytes;
  296.      RH->rh_Ptr+=RDBytes;
  297.      RH->rh_Left-=RDBytes;
  298.  
  299.      if (Bytes==0L) return Total;
  300.     }
  301.  
  302.    if (Bytes>=RH->rh_DG.dg_SectorSize)
  303.     {
  304.      RH->rh_IO->io_Command=CMD_READ;
  305.      RH->rh_IO->io_Length=(Bytes/RH->rh_DG.dg_SectorSize)*RH->rh_DG.dg_SectorSize;
  306.      RH->rh_IO->io_Data=Buffer;
  307.      RH->rh_IO->io_Offset=RH->rh_Pos;
  308.      if (DoIO((struct IORequest *)RH->rh_IO)) return -1L;
  309.  
  310.      RDBytes=RH->rh_IO->io_Actual;
  311.      RH->rh_Pos+=RDBytes;
  312.  
  313.      Buffer+=RDBytes;
  314.      Bytes-=RDBytes;
  315.      Total+=RDBytes;
  316.  
  317.      if (Bytes==0L) return Total;
  318.     }
  319.  
  320.    RH->rh_IO->io_Command=CMD_READ;
  321.    RH->rh_IO->io_Length=RH->rh_DG.dg_SectorSize;
  322.    RH->rh_IO->io_Data=RH->rh_Buffer;
  323.    RH->rh_IO->io_Offset=RH->rh_Pos;
  324.    if (DoIO((struct IORequest *)RH->rh_IO)) return -1L;
  325.  
  326.    RH->rh_Ptr=RH->rh_Buffer;
  327.    RH->rh_Left=RH->rh_IO->io_Actual;
  328.   }
  329.  return Total;
  330. }
  331.  
  332. LONG __regargs RawWrite(struct DHHandle *RH,UBYTE *Buffer,LONG Bytes)
  333.  
  334. {
  335.  LONG Total,WRBytes;
  336.  
  337.  if ((RH->rh_Pos+Bytes)>RH->rh_Len) Bytes=RH->rh_Len-RH->rh_Pos;
  338.  
  339.  Total=0L;
  340.  while (Bytes)
  341.   {
  342.    if (RH->rh_Left==RH->rh_DG.dg_SectorSize)
  343.     if (Bytes>=RH->rh_DG.dg_SectorSize)
  344.      {
  345.       RH->rh_IO->io_Command=CMD_WRITE;
  346.       RH->rh_IO->io_Length=(Bytes/RH->rh_DG.dg_SectorSize)*RH->rh_DG.dg_SectorSize;
  347.       RH->rh_IO->io_Data=Buffer;
  348.       RH->rh_IO->io_Offset=RH->rh_Pos;
  349.       if (DoIO((struct IORequest *)RH->rh_IO)) return -1L;
  350.  
  351.       WRBytes=RH->rh_IO->io_Actual;
  352.       RH->rh_Pos+=WRBytes;
  353.  
  354.       Buffer+=WRBytes;
  355.       Bytes-=WRBytes;
  356.       Total+=WRBytes;
  357.  
  358.       if (Bytes==0L) return Total;
  359.      }
  360.  
  361.    WRBytes=MIN(RH->rh_Left,Bytes);
  362.    (void)memcpy(RH->rh_Ptr,Buffer,WRBytes);
  363.  
  364.    Buffer+=WRBytes;
  365.    Bytes-=WRBytes;
  366.    Total+=WRBytes;
  367.  
  368.    RH->rh_Pos+=WRBytes;
  369.    RH->rh_Ptr+=WRBytes;
  370.    RH->rh_Left-=WRBytes;
  371.  
  372.    if (RH->rh_Left==0L)
  373.     {
  374.      RH->rh_IO->io_Command=CMD_WRITE;
  375.      RH->rh_IO->io_Length=RH->rh_DG.dg_SectorSize;
  376.      RH->rh_IO->io_Data=RH->rh_Buffer;
  377.      RH->rh_IO->io_Offset=RH->rh_Pos-RH->rh_DG.dg_SectorSize;
  378.      if (DoIO((struct IORequest *)RH->rh_IO)) return -1L;
  379.  
  380.      RH->rh_Ptr=RH->rh_Buffer;
  381.      RH->rh_Left=RH->rh_DG.dg_SectorSize;
  382.     }
  383.   }
  384.  return Total;
  385. }
  386.